/**
 * @author Dylan Jones, Ryan Hammonds
 */

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

public class SHA1Hash {
	
	public static int[] ShaHash (String s){
		byte[] bytes = s.getBytes();
		int ml = bytes.length;
		int i,j,c;
		long t;
		int[] h = new int[5];
		h[0] = 0x67452301;
		h[1] = 0xEFCDAB89;
		h[2] = 0x98BADCFE;
		h[3] = 0x10325476;
		h[4] = 0xC3D2E1F0;
		int lengthDiff = ml%64;
		byte[] newBytes;
		if(lengthDiff < 56){
			newBytes = new byte[ml+64-lengthDiff]; //append 64-diff
		} else if(lengthDiff > 55){
			newBytes = new byte[ml+128-lengthDiff]; //apppend 128-diff
		} else {
			newBytes = new byte[ml+8]; //append 8
		}
		for(i = 0; i < bytes.length; i++){
			newBytes[i] = bytes[i]; //copy over bytes into new array
		}
		newBytes[i] |= 0x80;
		long length = ((long) s.length())*8;
		long mask = 0xFF;
		for(i = 0; i < 8; i++){
			newBytes[newBytes.length-i-1] = (new Long((length&mask)>>i*8)).byteValue();
			mask <<= 8;
		}
		
		int[] ht = new int[7]; //a-0,b-1,c-2,d-3,e-4,f-5,temp-6
		ByteBuffer a = java.nio.ByteBuffer.wrap(newBytes);
		int[] ints = new int[newBytes.length/4];
		for(int l = 0; l < newBytes.length/4; l++){
			ints[l] = a.getInt(l*4);
		}
		for(i = 0; i < newBytes.length; i += 64){
			int[] w = new int[80];
			for(j = 0; j < 5; j++)
				ht[j] = h[j];
			for(j = 0; j < 16; j++){
				w[j] = a.getInt(i+j*4);
			}
			for(j = 16; j < 80; j++){
				w[j] = (w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16]);
				w[j] = Integer.rotateLeft(w[j], 1);
			}
			for(j = 0; j < 80 ; j++){
				if(j<20){
					ht[5] = (ht[1] & ht[2]) | ((~ht[1]) & ht[3]);
					c = 0x5A827999;
				} else if(j<40){
					ht[5] = ht[1] ^ ht[2] ^ ht[3];
					c = 0x6ED9EBA1;
				} else if(j<60){
					ht[5] = (ht[1] & ht[2]) | (ht[1] & ht[3]) | (ht[2] & ht[3]); 
					c = 0x8F1BBCDC;
				} else {
					ht[5] = ht[1] ^ ht[2] ^ ht[3];
					c = 0xCA62C1D6;
				}
				ht[6] = ht[0];
				ht[6] = Integer.rotateLeft(ht[6], 5);
				t = ht[6]+ht[4]+ht[5]+c+w[j];
				ht[4] = ht[3];
				ht[3] = ht[2];
				ht[1] = Integer.rotateLeft(ht[1], 30);
				ht[2] = ht[1];
				ht[1] = ht[0];
				ht[0] = (int) t;
			}
			for(j = 0; j < 5; j++){
				h[j] += ht[j];
			}
		}
		return h;
	}
	
	public static void main (String Args[]) throws UnsupportedEncodingException, NoSuchAlgorithmException{
		int[] h1 = {};
		Random rand = new Random();
		int i = 56;
		boolean allEqual = true;
		MessageDigest md = MessageDigest.getInstance("SHA-1");
		md.reset();
		for(i = 0; i <= 5000; i++){
			char[] chars = new char[i];
			for(int j = 0; j < i; j++){
				chars[j] = (char) (rand.nextInt(94)+' ');
			}
			String str = String.valueOf(chars);
			h1 = ShaHash(str);
			md.update(str.getBytes("utf8"));
			ByteBuffer a = java.nio.ByteBuffer.wrap(md.digest());
			boolean equal = true;
			for (int k=0; k< h1.length; k++){
				equal = (h1[k]==a.getInt(k*4))?equal:false;
			}
			System.out.println(chars.length+" "+equal+" "+(h1.length==5)+" "+h1.length+" "+5);
			allEqual = (equal&&(h1.length==5))?allEqual:false;
		}
		System.out.println("All Equal:"+allEqual);
	}

}
